package com.msmall.base.rms.manager.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.msmall.base.CascadeCollection;
import com.msmall.base.MD5;
import com.msmall.base.PaginationSupport;
import com.msmall.base.rms.manager.RMSManager;
import com.msmall.base.rms.mapper.AdministerMapper;
import com.msmall.base.rms.mapper.ModuleMapper;
import com.msmall.base.rms.po.Administer;
import com.msmall.base.rms.po.AdministerGroup;
import com.msmall.base.rms.po.Group;
import com.msmall.base.rms.po.GroupModule;
import com.msmall.base.rms.po.Module;
import com.msmall.base.rms.util.RMSUtils;

@Service("rmsManager")
public class RMSManagerImpl implements RMSManager{
	
	private static final Logger log = Logger.getLogger(RMSManagerImpl.class);
	
	@Autowired
	private AdministerMapper administerMapper;

	@Autowired
	private ModuleMapper moduleMapper;
	/**
	 * @Autowired public void setAdministerMapper(@Qualifier("administerMapper")
	 *            AdministerMapper administerMapper) { this.administerMapper =
	 *            administerMapper; }
	 */
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public Administer getAdminister(String username) {
		List<Administer> administers = administerMapper.selectAdministerByUsername(username);
		if(administers == null){
			return null;
		}else if(administers.size() == 1){
			return administers.get(0);
		}else {
			log.error(" ========> More Than one Administer :" + username);
			return null;
		}
	}
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public Administer getAdminister(Integer id) throws Exception{
		Administer administer = administerMapper.selectAdministerByid(id);
		return administer;
	}
	@Transactional(propagation = Propagation.REQUIRED)
	public void saveAdminister(Administer administer) throws Exception{
		if(administer.getId() != null && administer.getId() > 0){
			administerMapper.updateAdminister(administer);
		}else{
			administerMapper.insertAdminister(administer);
		}
	}
	
	/**
	 * 检查用户是否有权限访问URL
	 */
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public Module getModuleByAdministerAndUrl(Integer administerid, String url) throws Exception{
		List<Module> modules = moduleMapper.selectModuleByAdministerAndUrl(administerid, url);
		if(modules == null || modules.size() == 0){
			log.error(" ========> No one module administerid:" + administerid + " url:"+url);
			return null;
		}else if(modules.size() == 1){
			return modules.get(0);
		}else {
			log.error(" ========> More Than one modules administerid:" + administerid + " url:"+url);
			return null;
		}
	}
	
	/**
	 * 获得一个用户所拥有权限的所有模块
	 */
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public List<Module> getModuleByAdminister(Integer administerid) throws Exception{
		return moduleMapper.selectModuleByAdminister(administerid);
	}
	/**
	 * 获得一个用户所拥有权限的所有模块 返回JSON
	 */
	public JSONObject getModuleByAdministerJson(Integer administerid) throws Exception{
		List<Module> modules = getModuleByAdminister(administerid);
		if(modules == null || modules.size() <= 0){
			return null;
		}
		CascadeCollection<Module> cs = new CascadeCollection<Module>();
		cs.parserInt(modules,Module.TOP_LEVEL_ID,  "id", "parentid", "id", CascadeCollection.ORDERS_ASC);
		JSONObject json = new JSONObject();
		List<CascadeCollection<Module>> topLevels = cs.getTopLevels();
		CascadeCollection<Module> top = topLevels.get(0);
		generateModuleTree(json, top, true);
		return json;
	}
	/**
	 * 给组授权模块 ，返回JSON
	 */
	@SuppressWarnings("rawtypes")
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public JSONObject getAuthModuleByAGroupJson(Integer groupid) throws Exception{
		List<Map> maps = moduleMapper.getAuthModuleByAGroupJson(groupid);
		if(maps == null || maps.size() <= 0){
			return null;
		}
		JSONObject json = new JSONObject();
		generateAuthModuleTree(json, maps);
		return json;
	}
	@SuppressWarnings("rawtypes")
	private void generateAuthModuleTree(JSONObject json, List<Map> maps){
//		Integer id;
		String moduleName;
		Integer parentid;
		Integer gmid;
		for(Map map:maps){
//			id = (Integer) (map.get("id") != null ? map.get("id") : 0);
			moduleName = (String) (map.get("moduleName") != null ? map.get("moduleName") : "");
			parentid = (Integer) (map.get("parentid") != null ? map.get("parentid") : 0);
			gmid = (Integer) (map.get("gmid") != null ? map.get("gmid") : 0);
			map.remove("moduleName");
			map.put("name", moduleName);
			
			map.remove("parentid");
			map.put("pId", parentid);
			
			map.put("open", true);
			
			if(gmid != null && gmid > 0){
				map.put("checked", true);
			}
		}
		json.put("items", maps);
	}
	private void generateModuleTree(JSONObject json, CascadeCollection<Module> cs, boolean isopen){
		if(cs.getCurrent().getType().compareTo(Module.TYPE_MODULE) == 0){
			json.put("moduleid", cs.getCurrent().getId());
			json.put("parentid", cs.getCurrent().getParentid());
			json.put("targetUrl", cs.getCurrent().getUrl());
			json.put("name", cs.getCurrent().getModuleName());
			if(isopen){
				json.put("open", true);
			}else{
				json.put("open", false);
			}
			if(cs.getChildren() != null && cs.getChildren().size() > 0){
				List<JSONObject> list = new ArrayList<JSONObject>();
				for(CascadeCollection<Module> module : cs.getChildren()){
					if(module.getCurrent().getType().compareTo(Module.TYPE_MODULE) == 0){
						JSONObject child = new JSONObject();
						generateModuleTree(child, module, false);
						list.add(child);
					}
				}
				if(list.size() > 0){
					json.put("children", list);
				}
			}
		}
	}
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public Module getModule(Integer moduleid) throws Exception{
		return moduleMapper.selectModuleByid(moduleid);
	}
	/**
	 * 保存
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public void saveModule(Module module) throws Exception{
		if(module.getId() != null && module.getId() > 0){
			moduleMapper.updateModule(module);
		}else{
			moduleMapper.insertModule(module);
		}
	}
	/**
	 * 分页查找
	 */
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public void searchModule(String moduleName, PaginationSupport page) throws Exception{
		List<Map<String, Object>> list = moduleMapper.findModulePage(moduleName, page.getStartIndex(), page.getPageSize());
		int count = moduleMapper.findModulePageCount(moduleName);
		page.setTotalCount(count);
		page.setItems(list);
	}
	/**
	 * 获得顶级的模块
	 */
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public List<Module> getTopModule() throws Exception{
		return moduleMapper.getChildrenModule(Module.TOP_LEVEL_ID);
	}
	/**
	 * 获得模块的父模块列表
	 */
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public List<Module> getParentModule(Integer moduleid) throws Exception{
		return moduleMapper.getParentModule(moduleid);
	}
	/**
	 * 获得模块的子模块列表
	 */
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public List<Module> getChildrenModule(Integer moduleid) throws Exception{
		return moduleMapper.getChildrenModule(moduleid);
	}
	/**
	 * 物理删除，同时删除。相关的组关系
	 * @throws Exception
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public void removeModule(Integer moduleid) throws Exception{
		moduleMapper.deleteGroupModuleByModule(moduleid);
		moduleMapper.deleteModule(moduleid);
	}
	
	/**
	 * 分页查找
	 */
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public void searchGroup(String groupName, PaginationSupport page) throws Exception{
		List<Group> list = moduleMapper.findGroupPage(groupName, page.getStartIndex(), page.getPageSize());
		int count = moduleMapper.findGroupPageCount(groupName);
		page.setTotalCount(count);
		page.setItems(list);
	}
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public Group getGroup(Integer groupid) throws Exception{
		return moduleMapper.selectGroupByid(groupid);
	}
	/**
	 * 保存组的同事，保存组与模块的授权关系
	 * @param group
	 * @param modules需要授权的模块ID ，以英文,分割
	 * @throws Exception
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public void saveGroup(Group group, String moduleids) throws Exception{
		if(group.getId() == null || group.getId() == 0){
			moduleMapper.insertGroup(group);
		}else{
			moduleMapper.updateGroup(group);
		}
		if(StringUtils.isNotEmpty(moduleids)){
			moduleMapper.deleteGroupModuleByGroup(group.getId());
			String[] ids = moduleids.split(",");
			GroupModule gm;
			for(String moduleid : ids){
				if(StringUtils.isNotEmpty(moduleid)){
					gm = new GroupModule();
					gm.setGroupid(group.getId());
					gm.setModuleid(Integer.valueOf(moduleid.trim()));
					moduleMapper.insertGroupModule(gm);
				}
			}
		}
	}
	/**
	 * 物理删除，同时删除相关的与管理员授权，与模块授权关系
	 * @throws Exception
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public void removeGroup(Integer groupid) throws Exception{
		moduleMapper.deleteGroupModuleByGroup(groupid);
		moduleMapper.deleteAdministerGroupByGroup(groupid);
		moduleMapper.deleteGroup(groupid);
	}
	
	/**
	 * 分页查找
	 */
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public void searchAdminister(String username, PaginationSupport page) throws Exception{
		List<Administer> list = administerMapper.findAdministerPage(username, page.getStartIndex(), page.getPageSize());
		int count = administerMapper.findAdministerPageCount(username);
		page.setTotalCount(count);
		page.setItems(list);
	}
	
	/**
	 * 物理删除，同时删除相关的与组授权
	 * @throws Exception
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public void removeAdminister(Integer administerid) throws Exception{
		administerMapper.deleteAdministerGroupByAdminister(administerid);
		administerMapper.deleteAdminister(administerid);
	}
	/**
	 * 修改用户密码
	 * @param administer
	 * @throws Exception
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public void modifyPassword(Administer administer) throws Exception{
		administer.setPassword(MD5.getMD5(administer.getPassword()));
		administerMapper.updateAdministerPassword(administer);
	}
	
	/**
	 * 给管理员付权。每次在页面传递一个组ID
	 * action=1,增加权限;action=-1取消权限
	 *  RMSUtils.AUTH_ACTION_*
	 * @param administerid
	 * @param groupid
	 * @throws Exception
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public boolean authAdministerGroup(Integer administerid, Integer groupid, String action) throws Exception{
		try{
			if(RMSUtils.AUTH_ACTION_ADD.equals(action)){
				AdministerGroup administerGroup = new AdministerGroup();
				administerGroup.setAdministerid(administerid);
				administerGroup.setGroupid(groupid);
				administerMapper.insertAdministerGroup(administerGroup);
			}else if(RMSUtils.AUTH_ACTION_REMOVE.equals(action)){
				administerMapper.deleteAdministerGroup(administerid, groupid);
			}else{
				return false;
			}
			return true;
		}catch(Exception e){
			return false;
		}
	}
	/**
	 * 获得所有的组信息
	 * @throws Exception
	 */
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public List<Group> getAllGroup() throws Exception{
		List<Group> all = moduleMapper.selectAllGroup();
		return all;
	}
	/**
	 * 获得用户所有的组信息
	 * @throws Exception
	 */
	@Transactional(propagation = Propagation.NOT_SUPPORTED)
	public List<Group> getGroupByAdminister(Integer administerid) throws Exception{
		List<Group> auth = moduleMapper.selectGroupByAdminister(administerid);
		return auth;
	}
}
